;***********************************************************************
; spinlock_64.asm
;
; provides a basic in-kernel spinlock for SMP synchronisation
;
; Author: Aidan Goddard 4/10/13
;
; Uses portions of code from http://wiki.osdev.org/Spinlock
;
;***********************************************************************

section .text

global BakeryEnter
global BakeryLeave

;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
; spinlock entry
; rdi = ptr to 512-byte lock structure
; rsi = CPU ID

BakeryEnter:
	; attempt to acquire the lock
	mov			eax, 0
	lock bts	[rdi], eax
	jnc			.acquired
	
.retest:
	; check if the lock is free before trying again
	pause
	test		DWORD [rdi], 1
	jnz			.retest
	
	; lock is open, attempt to acquire it
	mov			eax, 0
	lock bts	[rdi], eax
	jc			.retest
	
.acquired:
	; lock is acquired, continue into critical region
	ret


;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
; spinlock exit
; rdi = ptr to 512-byte lock structure
; rsi = CPU ID

BakeryLeave:
	; release lock
	mov			[rdi], DWORD 0
	ret
